package com.shareach.redis;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;

import redis.clients.jedis.Tuple;

public class Redis{
	private NewJedisPool pool;//连接所属的池子
	
	public Redis(NewJedisPool pool){
		this.pool = pool;
	}
	
	private NewJedis getRedis(){
		NewJedis jedis = pool.getResource();
		jedis.connect();
		return jedis;
	}

    public void free(NewJedis jedis){
    	if (pool != null && jedis!=null) {
			pool.returnResource(jedis);
		}
    }

	
	public long lenList(String key) {
		NewJedis jedis = getRedis();
		try {
			return jedis.llen(key);
		} finally {
			free(jedis);
		}
	}

	
	public List<String> getFromList(String key, int startOffset, int totalNum) {
		NewJedis jedis = getRedis();
		try {
			return jedis.lrange(key, startOffset, startOffset+totalNum-1);
		} finally {
			free(jedis);
		}
	}

	
	public boolean isContainsSet(String key,String value){
		NewJedis jedis = getRedis();
		try {
			return jedis.sismember(key, value);
		} finally {
			free(jedis);
		}
	}

	public boolean isContainsSortedSet(String key,String value){
		NewJedis jedis = getRedis();
		try {
			Double r = jedis.zscore(key, value);
			return (r!=null);
		} finally {
			free(jedis);
		}
	}
	
	
	public List<String> trimFromList(String key, int totalNum) {
		NewJedis jedis = getRedis();
		try {
			return jedis.lrange(key,0,totalNum-1);
		} finally {
			jedis.ltrim(key, totalNum-1, jedis.llen(key));
			free(jedis);
		}
	}

	
	public void addSet(String key, String value) {
		NewJedis jedis = getRedis();
		try {
			jedis.sadd(key, value);
		} finally {
			free(jedis);
		}
	}
	
	
	public void removeSet(String key, String value) {
		NewJedis jedis = getRedis();
		try {
			jedis.srem(key, value);
		} finally {
			free(jedis);
		}
	}
	
	
	public void removeSet(String key, Set<String> valueSet) {
		NewJedis jedis = getRedis();
		try {
			jedis.srem(key, valueSet);
		} finally {
			free(jedis);
		}
	}
	
	/**
	 * 以当前时间的毫秒数位score
	 */
	
	public void addSortedSet(String key, String value) {
		NewJedis jedis = getRedis();
		try {
			jedis.zadd(key, System.currentTimeMillis(), value);
		} finally {
			free(jedis);
		}
	}
	public void addSortedSet(String key, String value,double score){
		NewJedis jedis = getRedis();
		try {
			jedis.zadd(key, score, value);
		} finally {
			free(jedis);
		}
	}
	public void addSortedSet(String key, Map<Double,String> scoreMembers){
		NewJedis jedis = getRedis();
		try {
			jedis.zadd(key, scoreMembers);
		} finally {
			free(jedis);
		}
	}
	
	public String getSortedSetHighestScoreVal(String key) {
		NewJedis jedis = getRedis();
		try {
			Set<String> set = jedis.zrevrange(key, 0, 0);
			if (CollectionUtils.isEmpty(set)) {
				return null;
			}
			
			return (String) CollectionUtils.get(set, 0);
		} finally {
			free(jedis);
		}
	}
	

	/**
	 * 获取指定范围的Member和Score ， 大到小
	 * @param key
	 * @param ticks
	 * @param count
	 * @return
	 */
	public Set<String> getSetScoresRevRange(String key, int start, int count){
		NewJedis jedis = getRedis();
		try {
			return jedis.zrevrange(key, start, start+count);//+.zrevrangeByScore(key, System.currentTimeMillis()+3600000, ticks, 0, count);
		} finally {
			free(jedis);
		}
	}
	
	/**
	 * 获取指定范围的Member和Score , 小到大
	 * @param key
	 * @param ticks
	 * @param count
	 * @return
	 */
	public Set<Tuple> getSetScoresRangeWithScores(String key, long start, long count){
		NewJedis jedis = getRedis();
		try {
			return jedis.zrangeWithScores(key, start, start+count);
		} finally {
			free(jedis);
		}
	}
	
	/**
	 * 获取指定范围的Member , 小到大
	 * @param key
	 * @param ticks
	 * @param count
	 * @return
	 */
	public Set<String> getSetScoresRange(String key, long start, long count){
		NewJedis jedis = getRedis();
		try {
			return jedis.zrange(key, start, start+count);//+.zrevrangeByScore(key, System.currentTimeMillis()+3600000, ticks, 0, count);
		} finally {
			free(jedis);
		}
	}
	/**
	 * 获取指定范围的Member和Score 
	 * @param key
	 * @param ticks
	 * @param count
	 * @return
	 */
	public Set<Tuple> getSetScoresRevRangeWithScore(String key, long start, long count){
		NewJedis jedis = getRedis();
		try {
			return jedis.zrevrangeWithScores(key, start, start+count);//+.zrevrangeByScore(key, System.currentTimeMillis()+3600000, ticks, 0, count);
		} finally {
			free(jedis);
		}
	}
	/**
	 * 获取score值大于 ticks的列表，数量未count 
	 * @param key
	 * @param ticks
	 * @param count
	 * @return
	 */
	public Set<String> getSetScores(String key, long ticks, int count){
		NewJedis jedis = getRedis();
		try {
			return jedis.zrevrangeByScore(key, System.currentTimeMillis()+3600000, ticks, 0, count);
		} finally {
			free(jedis);
		}
	}
	public Set<String> getSetScores(String key, long min, long max, int offset, int count){
		NewJedis jedis = getRedis();
		try {
			return jedis.zrevrangeByScore(key, min, max, offset, count);
		} finally {
			free(jedis);
		}
	}
	public Set<Tuple> getSetScoresWithScore(String key, long min, long max, int offset, int count){
		NewJedis jedis = getRedis();
		try {
			return jedis.zrangeByScoreWithScores(key, min, max, offset, count);
		} finally {
			free(jedis);
		}
	}
	
	/**
	 * 获取指定key中Set的数量
	 * @param key
	 * @return
	 */
	public int getSetCount(String key) {
		NewJedis jedis = getRedis();
		try {
			return jedis.scard(key).intValue();
		} finally {
			free(jedis);
		}
	}


	public long getSortedSetCount(String key) {
		NewJedis jedis = getRedis();
		try {
			return jedis.zcard(key).longValue();
		} finally {
			free(jedis);
		}
	}

	public Long getSortedSetCount(String key, long min, long max) {
		NewJedis jedis = getRedis();
		try {
			return jedis.zcount(key, min, max);//.zcard(key).intValue();
		} finally {
			free(jedis);
		}
	}

	/**
	 * 获取score值大于 ticks的列表，数量未count 
	 * @param key
	 * @param ticks
	 * @param count
	 * @return
	 */
	public Set<String> getSetScores(String key, long ticks, long max, int count){
		NewJedis jedis = getRedis();
		try {
			return jedis.zrevrangeByScore(key, max, ticks, 0, count);
		} finally {
			free(jedis);
		}
	}
	public Set<String> getSetByScoreRange(String key, double min, double max){
		NewJedis jedis = getRedis();
		try {
			return jedis.zrangeByScore(key, min, max);//.zrevrange(key, start, end).zrevrangeByScore(key, System.currentTimeMillis()+3600000, ticks, 0, count);
		} finally {
			free(jedis);
		}
	}

	
	public void removeSortedSet(String key, String value) {
		NewJedis jedis = getRedis();
		try {
			jedis.zrem(key, value);
		} finally {
			free(jedis);
		}
	}
	
	public void removeSortedSet(String key, double min, double max) {
		NewJedis jedis = getRedis();
		try {
			jedis.zremrangeByScore(key, min, max);
		} finally {
			free(jedis);
		}
	}
	
	
	public long lenSet(String key) {
		NewJedis jedis = getRedis();
		try {
			return jedis.scard(key);
		} finally {
			free(jedis);
		}
	}

	
	public Set<String> getInterSet(String key, String otherKey) {
		NewJedis jedis = getRedis();
		try {
			return jedis.sinter(key,otherKey);
		} finally {
			free(jedis);
		}
	}

	
	public Set<String> getDiffSet(String key, String otherKey) {
		NewJedis jedis = getRedis();
		try {
			return jedis.sdiff(key,otherKey);
		} finally {
			free(jedis);
		}
	}

	
	public String getHashValue(String key,String fieldName) {
		NewJedis jedis = getRedis();
		try {
			String count =  jedis.hget(key, fieldName);
			return count;
		} finally {
			free(jedis);
		}
	}
	
	
	public void delHashValue(String key, String listName) {
		NewJedis jedis = getRedis();
		try {
			jedis.hdel(key, listName);
		} finally {
			free(jedis);
		}
	}
	
	
	public Long setHashValue(String key, String field,String value) {
		NewJedis jedis = getRedis();
		try {
			return jedis.hset(key,field, value);
		} finally {
			free(jedis);
		}
	}
	
	/**
	 * 从Hash中取全部数据
	 * @param key
	 * @return
	 */
	
	public Map<String,String> getHashValues(String key){
		NewJedis jedis = getRedis();
		try {
			return  jedis.hgetAll(key);
		} finally {
			free(jedis);
		}
	}

	
	
	public long incr(String key) {
		NewJedis jedis = getRedis();
		try{
			long result = jedis.incr(key);
			return result;
		}finally{
			free(jedis);
		}
	}
	
	
	public long incr(String key, int value) {
		NewJedis jedis = getRedis();
		try{
			long result = jedis.incrBy(key, value);
			return result;
		}finally{
			free(jedis);
		}
	}

	
	public long decr(String key) {
		NewJedis jedis = getRedis();
		try{
			long result = jedis.decr(key);
			return result;
		}finally{
			free(jedis);
		}
	}

	
	public long decr(String key, int value) {
		NewJedis jedis = getRedis();
		try{
			long result = jedis.decrBy(key, value);
//			if (result < 1) {
//				result = 1;
//				jedis.set(key, String.valueOf(result));
//			}
			return result;
		}finally{
			free(jedis);
		}
	}

	
	public long incrH(String key, String member) {
		NewJedis jedis = getRedis();
		try{
			long result = jedis.hincrBy(key, member, 1);
			return result;
		}finally{
			free(jedis);
		}
	}

	
	public long incrH(String key, String member, int value) {
		NewJedis jedis = getRedis();
		try{
			long result = jedis.hincrBy(key, member, value);
			return result;
		}finally{
			free(jedis);
		}
	}

	
	public long decrH(String key, String member) {
		NewJedis jedis = getRedis();
		try{
			long result = jedis.hincrBy(key, member, -1);
			return result;
		}finally{
			free(jedis);
		}
	}

	
	public long decrH(String key, String member, int value) {
		NewJedis jedis = getRedis();
		try{
			long result = jedis.hincrBy(key, member, -value);
			return result;
		}finally{
			free(jedis);
		}
	}

	
	public long incrZ(String key, String member) {
		NewJedis jedis = getRedis();
		try{
			long result = jedis.zincrby(key, 1, member).longValue();
			return result;
		}finally{
			free(jedis);
		}
	}

	
	public long incrZ(String key, String member, int value) {
		NewJedis jedis = getRedis();
		try{
			long result = jedis.zincrby(key, value, member).longValue();
			return result;
		}finally{
			free(jedis);
		}
	}
	
	public String get(String key) {
		NewJedis jedis = getRedis();
		try{
			String result = jedis.get(key);
			return result;
		}finally{
			free(jedis);
		}
	}
	
	
	public String set(String key,String value) {
		NewJedis jedis = getRedis();
		try{
			String result = jedis.set(key,value);
			return result;
		}finally{
			free(jedis);
		}
	}

	public Set<String> getSet(String key){
		NewJedis jedis = getRedis();
		try {
			Set<String> md5 =  jedis.smembers(key);
			return md5;
		} finally {
			free(jedis);
		}
	}

	
	public Set<String> keys(String pattern) {
		NewJedis jedis = getRedis();
		try {
			return jedis.keys(pattern);
		} finally {
			free(jedis);
		}
	}
	
	
	public void del(String... keys) {
		NewJedis jedis = getRedis();
		//String[] str = new String[set.size()];
		try {
			jedis.del(keys);
		} finally {
			free(jedis);
		}
	}
	
	
	
	
	public Set<String> getSetInter(String... setKeys){
		NewJedis jedis = getRedis();
		try {
			return jedis.sinter(setKeys);
		} finally {
			free(jedis);
		}
	}

	
	public boolean isMember(String key, String value) {
		NewJedis jedis = getRedis();
		try {
			return jedis.sismember(key, value);
		} finally {
			free(jedis);
		}
	}

	
	public void publish(String channel,String message){
		NewJedis jedis = getRedis();
		try {
			jedis.publish(channel, message);
		} finally {
			free(jedis);
		}
	}

	
	public boolean hexist(String key, String listName) {
		NewJedis jedis = getRedis();
		try {
			return jedis.hexists(key, listName);
		} finally {
			free(jedis);
		}
	}

	
	public Double getSetScore(String key, String value) {
		NewJedis jedis = getRedis();
		try {
			return jedis.zscore(key, value);
		} finally {
			free(jedis);
		}
	}

	
	public Set<String> zrange(String key, int start, int stop) {
		NewJedis jedis = getRedis();
		try {
			return jedis.zrange(key, start, stop);
		} finally {
			free(jedis);
		}
	}
}
